﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using CommonLib.Util;
namespace CommonLib
{
	public class UIViewBase : MonoBehaviour, IUIView
	{
		/// <summary> 保持当前View的信息	/// </summary>
		[SerializeField]
		protected ViewInfor m_ViewInfor;

		/// <summary> 当前View的ID名称	/// </summary>
		public string ViewName { get { return m_ViewInfor.m_ViewName; } }
		/// <summary> 获取当前View的切换状态	/// </summary>
		public ViewType ViewType { get { return m_ViewInfor.m_UIViewType; } }

		protected UIViewBase PreView { get { return m_ViewInfor.m_PreView; } }
		protected UIViewBase CloseView { get { return m_ViewInfor.m_CloseView; } }

		/// <summary> 当前View的所有UI元素的字典	/// </summary>
		protected Dictionary<string, UIElementBase> ElementDic { get { return m_ViewInfor.m_ElementDic; } }

		public Dictionary<string, TweenAnimBase> AnimationOpen => m_ViewInfor.m_OpenAniamtion;
		public Dictionary<string, TweenAnimBase> AnimationClose => m_ViewInfor.m_CloseAniamtion;


		public Dictionary<string, UnityEvent> m_EventDic = new Dictionary<string, UnityEvent>();


		protected CanvasGroup ViewCanvasRender;
		protected Canvas ViewCanvas;
		protected GraphicRaycaster ViewCanvasRaycaster;
		#region Func

		private void Awake()
		{
			ViewInit();
		}

		/// <summary>
		/// 将UIViewBase进行初始化
		/// </summary>
		public virtual void ViewInit() {
			//从资源中初始化信息

			ViewCanvasRender	= gameObject.GetComponentIfMissing<CanvasGroup>();
			ViewCanvas			= gameObject.GetComponentIfMissing<Canvas>();
			ViewCanvasRaycaster = gameObject.GetComponentIfMissing<GraphicRaycaster>();
			//建立链接
			/*
			if (m_ViewInfor.m_ElementDic.TryGetValue(StringConst.S_Back, out UiElementBase back)) {
				back.AddListener(Back);
			}

			if (m_ViewInfor.m_ElementDic.TryGetValue(StringConst.S_Close, out UiElementBase close)) {
				close.AddListener(Close);
			}
			*/
			//初始化将m_ElementDic 和 m_EventDic 进行链接

			CreateByViewInfor(m_ViewInfor);
		}

		public virtual void Pause()
		{
			ViewCanvasRender.blocksRaycasts = false;
		}

		public virtual void Resume()
		{
			ViewCanvasRender.blocksRaycasts = true;
		}

		public virtual void Open()
		{
			//this.gameObject.SetActive(true);
			StartCoroutine(CorOpen());
		}

		/// <summary>
		/// 返回上一View
		/// </summary>
		public virtual void Back()
		{
			CallTimePoint(StringConst.S_View_PreBack);
			UIViewBase target = PreView ?? CloseView ?? null;
			if (null != target) {
				//UIViewManagerBase.Instance.ChangeView(this, target);
				ChangeView(target);
			}
			else
				Debug.LogWarning("Current View hasn't PreView or CloseView");
			CallTimePoint(StringConst.S_View_SufBack);
		}
		/// <summary> 
		/// 关闭当前View	
		/// </summary>
		public virtual void Close()
		{
			CallTimePoint(StringConst.S_View_PreClose);
			if (null != CloseView)
				//UIViewManagerBase.Instance.ChangeView(this, CloseView);
				ChangeView(CloseView);
			else
				Debug.LogError("Current View hasn't Close View");
			CallTimePoint(StringConst.S_View_SufClose);
		}
		//进行View跳转
		protected virtual void ChangeView(UIViewBase _target)
		{
			CallTimePoint(StringConst.S_View_PreChangeView);
			//UIViewManagerBase.Instance.ChangeView(this, _target);
			//this.gameObject.SetActive(false);
			StartCoroutine(CorClose());
			_target.Open();
			CallTimePoint(StringConst.S_View_SufChangeView);
		}


		protected virtual IEnumerator CorOpen()
		{
			CanvasRender(true);
			yield return null;
		}
		protected virtual IEnumerator CorClose() {
			CanvasRender(false);
			yield return null;
		}
		#endregion



		/// <summary>
		/// 将从ViewInfor的信息来创建View
		/// </summary>
		/// <param name="_infor"></param>
		protected virtual void CreateByViewInfor(ViewInfor _infor) {
			Debug.Log($"创建 { _infor.m_ViewName }");
			ViewCanvas.sortingLayerName = _infor.m_SortingLayer;
			ViewCanvas.sortingOrder = _infor.m_SortingOrder;
		}

		/// <summary>
		/// 同一调用时点函数接口
		/// </summary>
		/// <param name="_constName"></param>
		protected virtual void CallTimePoint(string _constName) {
			if (null == m_EventDic)
				return;
			if (m_EventDic.TryGetValue(_constName, out UnityEvent callEvent)) {
				if (SystemConfig.Debug) Debug.Log(new System.Text.StringBuilder(20, 20).Append("Call Time Point").Append(_constName).ToString());
				callEvent?.Invoke();
			}
		}

		protected virtual void CanvasRender(bool isVisable)
		{
			if (isVisable)
			{
				this.ViewCanvasRender.alpha = 1;
				this.ViewCanvasRender.blocksRaycasts = true;
				this.ViewCanvasRender.interactable = true;
			}
			else
			{
				this.ViewCanvasRender.alpha = 0;
				this.ViewCanvasRender.blocksRaycasts = false;
				this.ViewCanvasRender.interactable = false;
			}
		}
	}
}